package imper.main;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.newdawn.slick.Color;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.loading.LoadingList;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class ImageManager
{
	public final static int RESOURCE = 0;
	public final static int INDUSTRY = 1;
	public final static int CIVIL_UNIT = 2;
	public final static int ARMY_UNIT = 3;
	public final static int BOAT_UNIT = 4;
	public final static int LAND_TYPE = 5;
	public final static int FACILITIES = 6;
	public final static int ICONE = 7;
	
	/** Gestionnaire image */
	protected Map<Integer, Map<Integer, Image>> _image;

	/** instance */
	private static ImageManager _instance;

	/**
	 * Constructor
	 */
	protected ImageManager()
	{
		_image = new HashMap<Integer, Map<Integer, Image>>();
	}

	public static ImageManager getInstance()
	{
		if (_instance == null)
		{
			_instance = new ImageManager();
		}
		return _instance;
	}

	public void addImage(int pType, int pId, Image pImage)
	{
		Map<Integer, Image> imageTypeList = _image.get(pType);
		if (imageTypeList == null)
		{
			imageTypeList = new HashMap<Integer, Image>();
			_image.put(pType, imageTypeList);
		}
		imageTypeList.put(pId, pImage);
	}

	public Image getImage(int pType, int pId)
	{
		Map<Integer, Image> imageTypeList = _image.get(pType);
		if (imageTypeList != null)
		{
			return imageTypeList.get(pId);
		}
		return null;
	}
	
	public Integer nbImage(int pType)
    {
        Map<Integer, Image> imageTypeList = _image.get(pType);      
        return imageTypeList.size();
    }

	public boolean containsImage(int pType, int pId)
	{
		Map<Integer, Image> imageTypeList = _image.get(pType);
		if (imageTypeList != null)
		{
			return imageTypeList.containsKey(pId);
		}
		return false;
	}

	public void loadImage(InputStream is, boolean deferred) throws SlickException
	{
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = null;
		try
		{
			docBuilder = docBuilderFactory.newDocumentBuilder();
		}
		catch (ParserConfigurationException e)
		{
			throw new SlickException("Could not load resources", e);
		}
		Document doc = null;
		try
		{
			doc = docBuilder.parse(is);
		}
		catch (SAXException e)
		{
			throw new SlickException("Could not load resources", e);
		}
		catch (IOException e)
		{
			throw new SlickException("Could not load resources", e);
		}

		// normalize text representation
		doc.getDocumentElement().normalize();
		NodeList listResources = doc.getElementsByTagName("image");
		int totalResources = listResources.getLength();
		if (deferred)
		{
			LoadingList.setDeferredLoading(true);
		}

		for (int resourceIdx = 0; resourceIdx < totalResources; resourceIdx++)
		{
			Node resourceNode = listResources.item(resourceIdx);
			if (resourceNode.getNodeType() == Node.ELEMENT_NODE)
			{
				// resourceNode.
				Element resourceElement = (Element) resourceNode;

				String type = resourceElement.getAttribute("type");
				String path = resourceElement.getAttribute("path");
				String trans = resourceElement.getAttribute("trans");

				Image image = null;
				if (trans != null && !"".equals(trans))
				{
					image = new Image(path, false, Image.FILTER_NEAREST, new Color(Integer.parseInt(trans, 16)));
				}
				else
				{
					image = new Image(path);
				}

				NodeList listSprites = resourceElement.getElementsByTagName("sprite");
				int totalSprites = listSprites.getLength();
				for (int spriteIdx = 0; spriteIdx < totalSprites; spriteIdx++)
				{
					Node spriteNode = listSprites.item(spriteIdx);
					if (spriteNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element spriteElement = (Element) spriteNode;
						String id = spriteElement.getAttribute("id");
						String x = spriteElement.getAttribute("x");
						String y = spriteElement.getAttribute("y");
						String height = spriteElement.getAttribute("height");
						String width = spriteElement.getAttribute("width");
						Image img = image.getSubImage(Integer.valueOf(x), Integer.valueOf(y), Integer.valueOf(width), Integer.valueOf(height));
						addImage(Integer.valueOf(type), Integer.valueOf(id), img);
					}
				}
			}
		}
	}
}
